import { trim, isEmpty, merge, get } from 'lodash';
import { Op } from 'sequelize';
import BaseController from './base';
import SmsLogModel from '../models/sms-log';
import MiniUrlModel from '../models/mini-url';
import Client from '../utils/sms';
import dayjs from 'dayjs';
import { getSequelize } from '../db';
import WeApp from '../utils/weapp';
import HotelModel from '../models/hotel';
import SmsTemplateModel from '../models/sms-template';
import { eventBus } from '../utils/event-bus';
import UserModel from '../models/user';

const SMS_VALUE_MAP = {
  name: 'reservation.altName',
  hotelname: 'hotel.display_name',
  code: 'code'
}

function generateContent(smsTemplate, hotel, reservation, code) {
  // console.log(template)
  const root = {
    hotel,
    reservation,
    code
  }

  let content = smsTemplate.template_content;
  let params = smsTemplate.template_rule.split(',');

  const templateParam = {};

  for (const key of params) {
    const value = trim(get(root, SMS_VALUE_MAP[key], '')).replace('酒店', '');
    content = content.replace('${' + key + '}', value);
    templateParam[key] = value;
  }

  return {
    content,
    templateParam
  }
}

// order docs https://sequelize.org/docs/v6/core-concepts/model-querying-basics/
class SmsLogController extends BaseController {
  getModel() {
    return SmsLogModel;
  }

  /**
   * 解析查询条件
   * @returns {Object}
   */
  getFindWhere(req) {
    const {
      begin_date, end_date, user_id, confirm_number, mobile, status
    } = req.query;
    const { hotel_id } = req.user;

    const where = { hotel_id };
    if (user_id) {
      where.user_id = user_id;
    }

    if (confirm_number) {
      where.confirm_number = confirm_number;
    }

    if (mobile) {
      where.mobile = mobile;
    }

    if (status) {
      where.status = status;
    }

    where.created_at = {
      [Op.gte]: dayjs(begin_date).toISOString(),
      [Op.lt]: dayjs(end_date).add(1, 'days').toISOString()
    }

    return { where };
  }

  getInclude() {
    return {
      include: [{
        model: UserModel,
        as: 'user'
      }]
    };
  }

  async findAllBySequence(req, res, next) {
    try {
      const { hotel_id } = req.user;
      const { sequence } = req.params;
      const data = await SmsLogModel.findAll({
        where: {
          hotel_id,
          sequence
        },
        order: [['order_by', 'ASC']]
      });
      res.sendOk(data);
    }
    catch (e) {
      next(e);
    }
  }

  async bulkCreate(req, res, next) {
    try {
      const { hotel_id, id: user_id } = req.user;
      const reservations = req.body;
      const hotel = await HotelModel.findOne({ where: { id: hotel_id }, rejectOnEmpty: new Error('无效的酒店') });
      const smsTemplate = await SmsTemplateModel.findOne({ where: { hotel_id, template_code: hotel.sms_code }, rejectOnEmpty: new Error('无效的短信模板') });
      const access_token = await WeApp.getAccessToken(hotel_id);

      if (Array.isArray(reservations)) {
        const model = this.getModel();
        const sequence = dayjs().format('YYYYMMDDHHmmssSSS');
        const rows = [];
        for (const resv of reservations) {
          const row = {
            hotel_id,
            sequence,
            mobile: resv.PhoneNumber,
            confirm_number: resv.confirmNumber,
            url_id: null,
            sign_name: hotel.sign_name,
            sms_code: hotel.sms_code,
            content: null,
            template_param: '{}',
            status: 'INIT',
            result: null,
            user_id,
            order_by: 1
          };
          const data = await WeApp.generateUrlLink({ access_token, query: `confirmNumber=${resv.confirmNumber}` });
          let errmsg = '';
          if (data.errcode === 0) {
            try {
              const miniUrl = await MiniUrlModel.create({
                hotel_id,
                confirm_number: resv.confirmNumber,
                url: data.url_link,
              });

              const { content, templateParam } = generateContent(smsTemplate, hotel, resv, miniUrl.id);
              row.url_id = miniUrl.id;
              row.content = content;
              row.template_param = JSON.stringify(templateParam);
            } catch (e) {
              errmsg = e.message;
            }
          } else {
            errmsg = data.errmsg;
          }
          // data  { errcode: 0, errmsg: 'ok', url_link: 'https://wxaurl.cn/9yuIQ67Opqi' }
          if (errmsg) {
            row.status = 'FAILED';
            row.result = errmsg;
          }

          if (!row.mobile) {
            row.status = 'FAILED';
            row.result = '预订未预留手机号';
          }

          row.order_by = rows.length + 1;
          rows.push(row);
        }

        const transaction = await getSequelize().transaction();
        req.transaction = transaction;
        const data = await model.bulkCreate(rows, { transaction, req });
        await transaction.commit();
        eventBus.emit('send-sms', data, smsTemplate);
        res.sendOk(data);
      } else {
        throw new Error('请选择需要发送短信的预订');
      }
    }
    catch (e) {
      next(e);
    }
  }
}

export default new SmsLogController();
